package cn.wecloud.im.multiplayervideodemo.act

import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.os.SystemClock
import android.text.TextUtils
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.isVisible
import cn.wecloud.im.core.im.IMClient
import cn.wecloud.im.core.im.IMConversation
import cn.wecloud.im.core.im.IMMessageManager
import cn.wecloud.im.core.im.IMMultiMeetHandler
import cn.wecloud.im.core.im.callback.ICallback
import cn.wecloud.im.core.im.messages.MemberDto
import cn.wecloud.im.core.im.messages.MultiMeetEvent
import cn.wecloud.im.exception.WeException
import cn.wecloud.im.multiplayervideodemo.App
import cn.wecloud.im.multiplayervideodemo.Constant
import cn.wecloud.im.multiplayervideodemo.R
import cn.wecloud.im.multiplayervideodemo.ext.loadAvatar
import cn.wecloud.im.multiplayervideodemo.ext.loadUrl
import cn.wecloud.im.multiplayervideodemo.http.HttpException
import cn.wecloud.im.multiplayervideodemo.http.HttpManager
import cn.wecloud.im.multiplayervideodemo.http.SchedulerUtils
import cn.wecloud.im.multiplayervideodemo.http.errorConsumer
import cn.wecloud.im.multiplayervideodemo.live.MultiVideoArgs
import cn.wecloud.im.multiplayervideodemo.utils.AppSharePre
import cn.wecloud.im.multiplayervideodemo.utils.SoundPlayUtils
import kotlinx.android.synthetic.main.activity_meet_answer.*
import java.util.*

class MeetAnswerActivity : AppCompatActivity() {

    companion object {
        const val TO_CLIENT = "toClient"
        const val ROOM_ID = "roomId"
        const val CONV_ID = "convId"
        const val MEMBER_LIST = "memberList"

        fun startAnswer(
            content: Context,
            conversationId: Long,
            roomId: String,
            toClient: String,
            memberList: List<MemberDto>
        ) {
            val intent = Intent(
                content,
                MeetAnswerActivity::class.java
            ).putExtra(TO_CLIENT, toClient)
                .putExtra(ROOM_ID, roomId)
                .putExtra(CONV_ID, conversationId)
                .putParcelableArrayListExtra(MEMBER_LIST, ArrayList(memberList))
                .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
            content.startActivity(intent)
        }
    }

    private val roomId: String by lazy {
        intent.getStringExtra(ROOM_ID) ?: ""
    }
    private val conversationId: Long by lazy {
        intent.getLongExtra(CONV_ID, 0L)
    }
    private val inviteClientId: String by lazy {
        intent.getStringExtra(TO_CLIENT) ?: ""
    }

    private val memberList: ArrayList<MemberDto> by lazy {
        intent.getParcelableArrayListExtra(MEMBER_LIST)
            ?: throw NullPointerException("memberList is null!")
    }

    private var timer: Timer = Timer()

    private val multipleVideoReceiveCommand = object : IMMultiMeetHandler() {

        /**
         * 接收到RTC邀请
         */
        override fun processMultiMeetCallEvent(
            conversation: IMConversation?,
            data: MultiMeetEvent?
        ) {
            memberList.clear()
            memberList.addAll(data?.memberDtoList ?: emptyList())
        }

        /**
         * 有Client拒绝加入频道
         */
        override fun processMultiMeetRejectEvent(
            conversation: IMConversation?,
            data: MultiMeetEvent?
        ) {
            val cid = data?.clientId ?: return
            memberList.removeIf { it.clientId == cid }
        }

        /**
         * 有Client同意加入频道
         */
        override fun processMultiMeetAgreeEvent(
            conversation: IMConversation?,
            data: MultiMeetEvent?
        ) {
        }

        /**
         * 有Client离开频道
         */
        override fun processMultiMeetLeaveEvent(
            conversation: IMConversation?,
            data: MultiMeetEvent?
        ) {
            //邀请人取消呼叫
            val cid = data?.clientId ?: return
            if (cid == inviteClientId) {
                finish()
                return
            }
            memberList.removeIf { it.clientId == cid }
        }

        /**
         * Client占线
         */
        override fun processMultiMeetBusyEvent(
            conversation: IMConversation?,
            data: MultiMeetEvent?
        ) {
            val cid = data?.clientId ?: return
            memberList.removeIf { it.clientId == cid }
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_meet_answer)

        tvUserName.text = inviteClientId
        ivAvatar.loadAvatar("")

        tvCallStatus.text = "${getString(R.string.invite_you_to)}多人视频"

        ivBackGround.loadUrl("", R.mipmap.ic_avatar, true)
        groupMask.isVisible = true
        ivAnswerCaller.setOnClickListener {
            //接听
            joinRoom()
        }
        ivRefused.setOnClickListener {
            //拒绝
            refusedJoinRoom()
        }
        startCallTime()

        SoundPlayUtils.incomingTelegram()


        val timerTask = object : TimerTask() {
            override fun run() {
                finish()
                Handler(Looper.getMainLooper()).post {
                    Toast.makeText(
                        getApplication(), "呼叫超时",
                        Toast.LENGTH_LONG
                    ).show()
                }
            }
        }
        timer.schedule(timerTask, Constant.CALL_WAITING_TIME * 1000)
    }

    private fun joinRoom() {
        if (TextUtils.isEmpty(roomId))
            return
        val timestamp = System.currentTimeMillis().toString()
        val clientId = AppSharePre.getClientId()
        val appKey = App.APP_KEY
        val platform = 2
        val appSecret = App.APP_SECRET
        val d = HttpManager().getMultiMeetSign(timestamp, clientId, appKey, platform, appSecret)
            .flatMap {
                val sing = it.data
                if (TextUtils.isEmpty(sing))
                    throw HttpException(-1, "sing获取失败")
                HttpManager().joinMeetLive(roomId, clientId, appKey, sing!!, platform, timestamp)
            }
            .compose(SchedulerUtils.ioToMain())
            .subscribe({
                val token = it.data?.token ?: return@subscribe
                IMClient.getInstance()
                    .multiMeetAgree(conversationId, roomId, object : ICallback<Boolean>() {
                        override fun internalDone0(t: Boolean?, weException: WeException?) {
                            val args =
                                MultiVideoArgs(
                                    conversationId,
                                    roomId,
                                    token,
                                    inviteClientId,
                                    memberList
                                )
                            val intent =
                                MultipleVideoActivity.getIntent(this@MeetAnswerActivity, args)
                            startActivity(intent)
                            onBackPressed()
                        }
                    })
            }, errorConsumer { msg ->
                Toast.makeText(this,msg,Toast.LENGTH_SHORT).show()
            })
    }

    private fun refusedJoinRoom() {
        IMClient.getInstance()
            .multiMeetReject(conversationId, roomId, object : ICallback<Boolean>() {
                override fun internalDone0(t: Boolean?, weException: WeException?) {
                    onBackPressed()
                }
            })
    }

    override fun onStart() {
        super.onStart()
        IMMessageManager.registerMultiMeetMessageHandler(multipleVideoReceiveCommand)
    }

    override fun onStop() {
        IMMessageManager.unregisterMultiMeetMessageHandler(multipleVideoReceiveCommand)
        SoundPlayUtils.stopPlay()
        timer.cancel()
        super.onStop()
    }

    //开始计时通话时间
    private fun startCallTime() {
        tvTime.base = SystemClock.elapsedRealtime()
        tvTime.start()
    }

    override fun onDestroy() {
        if (tvTime != null) {
            tvTime.stop()
        }
        super.onDestroy()
    }
}